package com.ssy.lingxi.contract.esign.api;

import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.contract.esign.EsignProperties;
import com.ssy.lingxi.contract.esign.exception.EsignException;
import com.ssy.lingxi.contract.esign.util.ApiUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * 电子签名API聚合
 * 电子签名 SaaS API（非标版） https://open.esign.cn/doc/detail?id=opendoc%2Fpaas_api%2Fyvv8tt&namespace=opendoc%2Fpaas_api
 * @author yzc
 * @version 2.0.0
 * @date 2020/8/26
 */
@Slf4j
public class SignApi {

    private final AuthToken authToken;
    private final EsignProperties properties;

    public SignApi(AuthToken authToken, EsignProperties properties) {
        this.authToken = authToken;
        this.properties = properties;
    }

    // ============================电子签名============================
    /**
     * 步骤:
     * 1.个人账号创建
     * 2.机构账号创建
     * 3.创建个人/机构模板印章
     * 4.上传方式创建文件/上传方式创建模板接口
     * 5.签署流程创建接口
     * 6.流程文档添加
     * 7.流程附件添加
     * 8.添加平台自动盖章签署区/添加签署方自动盖章签署区/添加手动盖章签署区
     * 9.签署流程开启
     * 10.签署流程归档
     * 11.流程文档下载
     */

    /**
     * 签署方账户API
     */
    public Account account() {
        return new Account(authToken, properties);
    }

    /**
     * 印章服务API
     */
    public Seal seal() {
        return new Seal(authToken, properties);
    }

    /**
     * 文件模板API
     */
    public FileTemplate fileTemplate() {
        return new FileTemplate(authToken, properties);
    }

    /**
     * 签署服务API
     */
    public SignFlow signFlow() {
        return new SignFlow(authToken, properties);
    }

    /**
     * 辅助接口
     */
    public Helper helper() {
        return new Helper(authToken, properties);
    }


    // ============================实名认证============================
    /**
     *
     *步骤:
     *1.创建个人账户
     *2.创建企业账户
     *3.发起企业信息校验,支持4要素或3要素
     *4.主动轮询查询认证结果(可选)
     */

    /**
     * 信息比对
     */
    public MessageVerify messageVerify() {
        return new MessageVerify(authToken, properties);
    }

    /**
     * 个人认证
     */
    public PersonalAuth personalAuth() {
        return new PersonalAuth(authToken, properties);
    }

    /**
     * 企业认证
     */
    public OrganizationAuth enterpriseAuth() {
        return new OrganizationAuth(authToken, properties);
    }

    /**
     * 鉴权token
     */
    public AuthToken authToken() {
        return authToken;
    }


    public boolean verifySign(Map<String, String> headerMap, String data) {
        String appId = getIgnoreKey(headerMap, "x-tsign-open-app-id");
        String signature = getIgnoreKey(headerMap, "x-tsign-open-signature");
        String timestamp = getIgnoreKey(headerMap, "x-tsign-open-timestamp");
        String algorithm = getIgnoreKey(headerMap, "x-tsign-open-signature-algorithm");

        if (properties.isDebug()) {
            log.info("请求头信息: {}", JSONUtil.toJsonStr(headerMap));
            log.info("回调请求体结果: {}", data);
        }

        boolean verifySign = false;
        try {
            verifySign = ApiUtil.verifySign(signature, timestamp, data, properties.getAppSecret());
        } catch (EsignException e) {
            log.error(e.getError().toString());
            return false;
        }

        if (properties.isDebug()) {
            log.info("e签宝回调验签结果: {}", verifySign);
        }
        return verifySign;
    }

    private String getIgnoreKey(Map<String, String> headerMap, String key) {
        String value = headerMap.get(key.toLowerCase());
        if (value != null && !"".equals(value)) {
            return value;
        } else {
            return headerMap.get(key.toUpperCase());
        }
    }

    public EsignProperties getProperties() {
        return properties;
    }
}
